package com.nowcoder.community.controller;

import com.nowcoder.community.annotation.LoginRequired;
import com.nowcoder.community.entity.*;
import com.nowcoder.community.event.EventProducer;
import com.nowcoder.community.service.CommentService;
import com.nowcoder.community.service.DiscussPostService;
import com.nowcoder.community.service.LikeService;
import com.nowcoder.community.service.UserService;
import com.nowcoder.community.util.CommunityConstant;
import com.nowcoder.community.util.CommunityUtil;
import com.nowcoder.community.util.HostHolder;
import com.nowcoder.community.util.RedisKeyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

@Controller
@RequestMapping("/discuss")
public class DiscussPostController {

    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private DiscussPostService discussPostService;

    @Autowired
    private UserService userService;
    
    @Autowired
    private CommentService commentService;

    @Autowired
    private LikeService likeService;

    @Autowired
    private EventProducer eventProducer;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public String addDiscussPost(String title, String content) {
        User loginUser = hostHolder.getUser();
        DiscussPost discussPost = new DiscussPost();
        discussPost.setUserId(loginUser.getId());
        discussPost.setTitle(title);
        discussPost.setContent(content);
        discussPost.setType(0);
        discussPost.setStatus(0);
        discussPost.setCreateTime(new Date());
        discussPost.setCommentCount(0);
        discussPostService.addDiscussPost(discussPost);

        Map<String, Object> data = new HashMap<>();
        data.put("postId", discussPost.getId());

        // 触发发帖子事件，用于更新es中的帖子
        Event event = new Event()
                .setTopic(CommunityConstant.TOPIC_PUBLISH)
                .setUserId(loginUser.getId())
                .setEntityType(CommunityConstant.ENTITY_TYPE_POST)
                .setEntityId(discussPost.getId());
        eventProducer.produceEvent(event);

        // 将postId存入redis，用于定时任务更新帖子score
        String postScoreKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(postScoreKey, discussPost.getId());

        return CommunityUtil.getJSONString(0, "发布成功！", data);
    }

    @RequestMapping(value = "/detail/{discussPostId}", method = RequestMethod.GET)
    public String getDiscussPostDetail(Model model, Page page,
                                       @PathVariable("discussPostId") int discussPostId) {
        // 帖子
        DiscussPost post = discussPostService.findDiscussPostById(discussPostId);
        if (post == null) {
            throw new IllegalArgumentException("帖子不存在!");
        }
        model.addAttribute("post", post);

        // 发布该帖子的用户
        User user = userService.findUserById(post.getUserId());
        model.addAttribute("user", user);

        // 该帖子的点赞数
        model.addAttribute("likeCount", likeService.getEntityLikeCount(CommunityConstant.ENTITY_TYPE_POST, discussPostId));

        // 当前登录用户对该帖子的点赞状态
        User loginUser = hostHolder.getUser();
        boolean likeStatus = loginUser != null && likeService.getEntityLikeStatus(loginUser.getId(), CommunityConstant.ENTITY_TYPE_POST, post.getId());
        model.addAttribute("likeStatus", likeStatus);

        // 帖子评论的分页信息
        page.setRows(post.getCommentCount());
        page.setPath("/discuss/detail/" + discussPostId);

        // 帖子的评论列表
        List<Comment> comments = commentService.findCommentsByEntity(CommunityConstant.ENTITY_TYPE_POST, discussPostId, page.getLimit(), page.getOffset());
        // 评论ViewObject列表
        List<Map<String, Object>> commentVOList = new ArrayList<>();
        if (comments != null) {
            for (Comment comment : comments) {
                Map<String, Object> commentVO = new HashMap<>();
                // 当前评论
                commentVO.put("comment", comment);
                // 当前评论的作者
                commentVO.put("user", userService.findUserById(comment.getUserId()));
                // 当前评论的回复数
                commentVO.put("replyCount", commentService.findCommentRowsByEntity(CommunityConstant.ENTITY_TYPE_COMMENT, comment.getId()));
                // 当前评论的点赞数
                commentVO.put("likeCount", likeService.getEntityLikeCount(CommunityConstant.ENTITY_TYPE_COMMENT, comment.getId()));
                // 当前登录用户对评论的点赞状态
                likeStatus = loginUser != null && likeService.getEntityLikeStatus(loginUser.getId(), CommunityConstant.ENTITY_TYPE_COMMENT, comment.getId());
                commentVO.put("likeStatus", likeStatus);

                // 当前评论的回复列表
                List<Comment> replys = commentService.findCommentsByEntity(CommunityConstant.ENTITY_TYPE_COMMENT, comment.getId(), Integer.MAX_VALUE, 0);
                // 回复ViewObject列表
                List<Map<String, Object>> replyVOList = new ArrayList<>();
                if (replys != null) {
                    for (Comment reply : replys) {
                        Map<String, Object> replyVO = new HashMap<>();
                        // 当前回复
                        replyVO.put("reply", reply);
                        // 当前回复的作者
                        replyVO.put("user", userService.findUserById(reply.getUserId()));
                        // 当前回复的目标用户
                        replyVO.put("target", userService.findUserById(reply.getTargetId()));
                        // 当前回复的点赞数
                        replyVO.put("likeCount", likeService.getEntityLikeCount(CommunityConstant.ENTITY_TYPE_COMMENT, reply.getId()));
                        // 当前登录用户对回复的点赞状态
                        likeStatus = loginUser != null && likeService.getEntityLikeStatus(loginUser.getId(), CommunityConstant.ENTITY_TYPE_COMMENT, reply.getId());
                        replyVO.put("likeStatus", likeStatus);

                        replyVOList.add(replyVO);
                    }
                }
                commentVO.put("replyList", replyVOList);

                commentVOList.add(commentVO);
            }
        }
        model.addAttribute("commentList", commentVOList);

        return "/site/discuss-detail";
    }

    @RequestMapping(value = "/top", method = RequestMethod.POST)
    @ResponseBody
    public String setTop(int postId) {
        Map<String, Object> data = new HashMap<>();
        DiscussPost post = discussPostService.findDiscussPostById(postId);
        if (post.getType() == 0) {
            discussPostService.updateType(postId, 1);
            data.put("topped", true);
        } else {
            discussPostService.updateType(postId, 0);
            data.put("topped", false);
        }

        // 触发发帖事件，更新es中的帖子
        Event event = new Event()
                .setTopic(CommunityConstant.TOPIC_PUBLISH)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(CommunityConstant.ENTITY_TYPE_POST)
                .setEntityId(postId);
        eventProducer.produceEvent(event);

        return CommunityUtil.getJSONString(0, null, data);
    }

    @RequestMapping(value = "/promote", method = RequestMethod.POST)
    @ResponseBody
    public String setPromote(int postId) {
        Map<String, Object> data = new HashMap<>();
        DiscussPost post = discussPostService.findDiscussPostById(postId);
        if (post.getStatus() == 0) {
            discussPostService.updateStatus(postId, 1);
            data.put("promoted", true);
        } else {
            discussPostService.updateStatus(postId, 0);
            data.put("promoted", false);
        }

        // 触发发帖事件，更新es中的帖子
        Event event = new Event()
                .setTopic(CommunityConstant.TOPIC_PUBLISH)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(CommunityConstant.ENTITY_TYPE_POST)
                .setEntityId(postId);
        eventProducer.produceEvent(event);

        // 将postId存入redis，用于定时任务更新帖子score
        String postScoreKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(postScoreKey, postId);

        return CommunityUtil.getJSONString(0, null, data);
    }

    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public String setDelete(int postId) {
        discussPostService.updateStatus(postId, 2);

        // 触发删帖事件，更新es中的帖子
        Event event = new Event()
                .setTopic(CommunityConstant.TOPIC_DELETE)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(CommunityConstant.ENTITY_TYPE_POST)
                .setEntityId(postId);
        eventProducer.produceEvent(event);

        return CommunityUtil.getJSONString(0, null);
    }

}
